/**
 * Copyright (c) 2006-2017, JGraph Ltd
 * Copyright (c) 2006-2017, Gaudenz Alder
 */
/**
 * Class: mxTemporaryCellStates
 *
 * Creates a temporary set of cell states.
 */
function mxTemporaryCellStates(view, scale, cells, isCellVisibleFn, getLinkForCellState) {
    scale = (scale != null) ? scale : 1;
    this.view = view;

    // Stores the previous state
    this.oldValidateCellState = view.validateCellState;
    this.oldBounds = view.getGraphBounds();
    this.oldStates = view.getStates();
    this.oldScale = view.getScale();
    this.oldDoRedrawShape = view.graph.cellRenderer.doRedrawShape;

    var self = this;

    // Overrides doRedrawShape and paint shape to add links on shapes
    if (getLinkForCellState != null) {
        view.graph.cellRenderer.doRedrawShape = function (state) {
            var oldPaint = state.shape.paint;

            state.shape.paint = function (c) {
                var link = getLinkForCellState(state);

                if (link != null) {
                    c.setLink(link);
                }

                oldPaint.apply(this, arguments);

                if (link != null) {
                    c.setLink(null);
                }
            };

            self.oldDoRedrawShape.apply(view.graph.cellRenderer, arguments);
            state.shape.paint = oldPaint;
        };
    }

    // Overrides validateCellState to ignore invisible cells
    view.validateCellState = function (cell, resurse) {
        if (cell == null || isCellVisibleFn == null || isCellVisibleFn(cell)) {
            return self.oldValidateCellState.apply(view, arguments);
        }

        return null;
    };

    // Creates space for new states
    view.setStates(new mxDictionary());
    view.setScale(scale);

    if (cells != null) {
        view.resetValidationState();
        var bbox = null;

        // Validates the vertices and edges without adding them to
        // the model so that the original cells are not modified
        for (var i = 0; i < cells.length; i++) {
            var bounds = view.getBoundingBox(view.validateCellState(view.validateCell(cells[i])));

            if (bbox == null) {
                bbox = bounds;
            }
            else {
                bbox.add(bounds);
            }
        }

        view.setGraphBounds(bbox || new mxRectangle());
    }
};

/**
 * Variable: view
 *
 * Holds the width of the rectangle. Default is 0.
 */
mxTemporaryCellStates.prototype.view = null;

/**
 * Variable: oldStates
 *
 * Holds the height of the rectangle. Default is 0.
 */
mxTemporaryCellStates.prototype.oldStates = null;

/**
 * Variable: oldBounds
 *
 * Holds the height of the rectangle. Default is 0.
 */
mxTemporaryCellStates.prototype.oldBounds = null;

/**
 * Variable: oldScale
 *
 * Holds the height of the rectangle. Default is 0.
 */
mxTemporaryCellStates.prototype.oldScale = null;

/**
 * Function: destroy
 *
 * Returns the top, left corner as a new <mxPoint>.
 */
mxTemporaryCellStates.prototype.destroy = function () {
    this.view.setScale(this.oldScale);
    this.view.setStates(this.oldStates);
    this.view.setGraphBounds(this.oldBounds);
    this.view.validateCellState = this.oldValidateCellState;
    this.view.graph.cellRenderer.doRedrawShape = this.oldDoRedrawShape;
};